package task;

import java.util.Iterator;
import java.util.concurrent.*;
import node.NodeDescriptor;


public class rIQueue implements IQueue{

	private static final int ENQUEUE_UNKNOWN_ERROR 	= -1;
	private static final int ENQUEUE_OK 			= 0;
	private static final int ENQUEUE_MAX_SIZE_ERROR	= 1;
	
	private BlockingQueue<Task> realQueue = null;
	
	private rIQueueListener queueDelegate;
    	     

	public rIQueue()
	{
		super();
    	this.realQueue =  new LinkedBlockingQueue<Task>(NodeDescriptor.getInstance().getISize());
    	this.queueDelegate = null;
    }

    public synchronized int getCurrentSize()
    {
    	return this.realQueue.size();
    }
     
 	@Override
 	public synchronized int enqueue(Task t) {
 		try {
 			if(this.realQueue.size() < 
 					(int)(NodeDescriptor.getInstance().getISize() * NodeDescriptor.getInstance().getISubmission()))
 			{
 				realQueue.put(t);
 	
 				if(realQueue.size()==1 && this.queueDelegate!=null)
 					this.queueDelegate.queueHasGotElements(this, t);
 	
 				System.out.println(" >> NODE > rIQueue: Task enqueued into local queue: " + t);
 				return rIQueue.ENQUEUE_OK;
 			}
 			else
 				return rIQueue.ENQUEUE_MAX_SIZE_ERROR;
 	    }
 	    catch (InterruptedException e) {
 	        return rIQueue.ENQUEUE_UNKNOWN_ERROR;
 	    }
 	}

 	@Override
 	public synchronized Task dequeue() {
        Task tempTask = realQueue.poll();
        
        if(realQueue.isEmpty() && this.queueDelegate!=null)
        	this.queueDelegate.queueHasNoElements(this);
        
        //Queue.remove();
        System.out.println(" >> NODE > rIQueue: Dequeued from Local Queueu:\n >> " + tempTask);
        return tempTask; 
 	}
 	
 	public String toString()
 	{
 		String returnString = "LocalQueue: {";
 		
 		Iterator<Task> queueIt= this.realQueue.iterator();
 		while(queueIt.hasNext())
 		{
 			returnString += "\n\t" + queueIt.next() + ",\n";
 		}
 		returnString += "}";
 		
 		return returnString;
 	}
 	
 	public void setQueueDelegate(rIQueueListener newDelegate)
 	{
 		this.queueDelegate = newDelegate;
 	}
}
